﻿/**************************************************************************
创建时间:	2020/4/14 14:15:08    
作	  者:	张存
邮 	  箱:	zhangcunliang@126.com

描	述：
记	录：
***************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZhCun.Utils.Helpers;

namespace ZhCun.Win.Controls
{
    public class EditNumber : EditText
    {
        /// <summary>
        /// 
        /// </summary>
        public EditNumber()
        {
            this.TextAlign = HorizontalAlignment.Right;
            SetFormatText(true);
        }
        /// <summary>
        /// 值
        /// </summary>
        public decimal Value
        {
            get
            {
                string newText = Text.Replace(",", "");
                if (!PrefixSign.IsEmpty())
                {
                    newText = newText.Replace(PrefixSign, "");
                }
                decimal.TryParse(newText, out decimal val);
                return val;
            }
            set
            {
                Text = value.ToString();
                SetFormatText(true);
            }
        }
        /// <summary>
        /// 小数位数
        /// </summary>
        int _NumScale = 2;
        /// <summary>
        /// 是否正在设置文本，true 不触发 OnTextChanged 的自定义逻辑
        /// </summary>
        bool _IsSetText = false;
        /// <summary>
        /// 格式化时是否包含小数点
        /// </summary>
        bool HasPoint { get { return _FormatString.Contains("."); } }

        string _FormatString = "#,##0.00";
        /// <summary>
        /// 格式化字符串
        /// </summary>
        [Category("custom edit"), Description("格式化字符，#:占位符，0.00：格式及小数点")]
        public string FormatString
        {
            set
            {
                _FormatString = value;
                SetFormatText(true);
            }
            get { return _FormatString; }
        }

        string _PrefixSign = "￥";
        /// <summary>
        /// 符号前缀
        /// </summary>
        [Category("custom edit"), Description("前缀显示符号")]
        public string PrefixSign
        {
            set
            {
                _PrefixSign = value;
                SetFormatText(true);
            }
            get
            {
                return _PrefixSign;
            }
        }
        /// <summary>
        /// 实际返回值 等同于 Value
        /// </summary>
        public override object RealValue
        {
            get { return Value; }
            set
            {
                if (decimal.TryParse(value?.ToString(), out decimal dc))
                {
                    Value = dc;
                }
            }
        }
        /// <summary>
        /// 设置格式文本，指定是否加前缀
        /// </summary>
        void SetFormatText(bool isPrefix)
        {
            _IsSetText = true;
            Text = Value.ToString(_FormatString);
            if (isPrefix)
            {
                Text = PrefixSign + Text;
            }
            _NumScale = _FormatString.Length - _FormatString.IndexOf(".") - 1;
            _IsSetText = false;
        }
        /// <summary>
        /// 重置某个位置的文本内容
        /// </summary>
        void SetTextChar(char data, int index, int newIndex = -1)
        {
            if (newIndex < 0) newIndex = index;
            char[] txtChars = new char[TextLength];
            for (int i = 0; i < TextLength; i++)
            {
                if (index == i)
                {
                    txtChars[i] = data;
                }
                else
                {
                    txtChars[i] = Text[i];
                }
            }
            _IsSetText = true;
            Text = new string(txtChars);
            SelectionStart = newIndex;
            _IsSetText = false;
        }
        /// <summary>
        /// 验证输入内容
        /// </summary>
        bool VerifyInput(char keyChar)
        {
            if (SelectionStart == 0 && keyChar != '-')
            {
                if (keyChar != (char)Keys.Back &&
                    keyChar != (char)Keys.Delete &&
                    (keyChar < '0' || keyChar > '9') &&
                    keyChar != '.')
                {
                    return false;
                }
            }

            if (!HasPoint)
            {
                if (keyChar == '.') return false;
                return true;
            }
            if (keyChar == '.')
            {
                SelectionStart = TextLength - _NumScale;
                return false;
            }
            int pointIndex = Text.IndexOf('.');
            if (keyChar == (char)Keys.Back)
            {
                if (SelectionStart - 1 == pointIndex)
                {
                    SelectionStart -= 1;
                    return false;
                }
                if (SelectionStart - 1 < pointIndex)
                {
                    return true;
                }
                SetTextChar('0', SelectionStart - 1);
                return false;
            }
            if ((SelectionStart >= TextLength - _NumScale) ||
                (SelectionStart == 0 && SelectionStart == pointIndex - 1 && Text[SelectionStart] == '0')
                )
            {
                SetTextChar(keyChar, SelectionStart, SelectionStart + 1);
                return false;
            }
            return true;
        }
        /// <summary>
        /// 处理输入验证
        /// </summary>
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (!VerifyInput(e.KeyChar))
            {
                e.Handled = true;
                return;
            }
            base.OnKeyPress(e);
        }
        /// <summary>
        /// 重新格式化显示字符
        /// </summary>
        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
            if (_IsSetText) return;
            int lastFocusIndex = TextLength - SelectionStart;
            bool isEmpty = !Text.Contains(".");
            SetFormatText(DesignMode);
            int newIndex = TextLength - lastFocusIndex;
            if (newIndex < 0) newIndex = 0;
            SelectionStart = isEmpty && HasPoint ? 1 : newIndex;
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            SetFormatText(true);
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            SetFormatText(false);
        }
    }
}